#include "Serializable.h"


using namespace std;

ObjectSerializable::ObjectSerializable(const char* bytes, ssize_t objSize)
{       
    m_size = 0;
    m_bytesMap = NULL;
    
    if (bytes == NULL)
    {
      return;
    }
    
    const char* temp = bytes;
    
    char* keyValue[2];
    int keyLength[2];
    string currentKey, currentValue;
    
    int length = 0;
    int i = 0;
	ssize_t sizeProcessed = 0;
    
    while (bytes[0] != '\0' && sizeProcessed < objSize)
    {
      memcpy(&length, bytes, sizeof(int));
      bytes += sizeof(int);
      sizeProcessed += sizeof(int);
      
      if (bytes[0] != '\0')
      {
	keyValue[i] = new char[length + 1];
	memcpy(keyValue[i], bytes, length);
	keyLength[i] = length;
	bytes += length;
	sizeProcessed += length;
	++i;
      }
      
      if (i >= 2)
      {
	  currentKey.assign(keyValue[0],keyLength[0]);
	  currentValue.assign(keyValue[1],keyLength[1]);
	  
	  AddAttribute(currentKey,currentValue);
	  
	  i = 0;
	  delete[] keyValue[0];
	  delete[] keyValue[1];
      }
    }
    
    m_bytesMap = new char[m_size + 1];
    memcpy(m_bytesMap, temp, m_size );
}

ObjectSerializable::ObjectSerializable()
{
    m_bytesMap = NULL;
    m_size = 0;
}

ObjectSerializable::~ObjectSerializable()
{
    if (m_bytesMap != NULL)      
      delete[] m_bytesMap;
}

bool ObjectSerializable::AddAttribute(std::string name, std::string value )
{
    m_size += 2*sizeof(int) + name.size() + value.size();
    
    m_map[name] = value;
}

std::string ObjectSerializable::GetAttribute (std::string name)
{
    // chequear que existe name
    return m_map[name];
}

char* ObjectSerializable::Serialize()
{    
    std::map<string, string>::iterator it = m_map.begin();
    
    string currentKey, currentValue;
    int length = 0;
    
    char* temp = new char[m_size + 1];
    memset(temp,0, m_size);
    
    m_bytesMap = temp;
    
    for (it = m_map.begin(); it != m_map.end(); it++)
    {	
	currentKey = it->first;
	length = currentKey.length();	
	
	memcpy(temp, &length, sizeof(int));
	temp += sizeof(int);
	
	memcpy(temp, currentKey.c_str(), length);
	temp += length;
	
	currentValue = it->second;
	length = currentValue.length();	
	
	memcpy(temp, &length, sizeof(int));	
	temp += sizeof(int);
	
	memcpy(temp, currentValue.c_str(), length);
	temp += length;
    }    
    
    return m_bytesMap;
}

int ObjectSerializable::getSize()
{
	return m_size;
}
